﻿using System;
using System.Collections.Generic;

namespace SwyishChess.Domain.Piece
{
    public class Pawn : ChessPiece, IDiagonallyMovable, IVerticallyMovable
    {
        private const int MAXIMUM_DIAGONALLY_OVABLE_RANGE = 1;
        private const int MAXIMUM_VERTICALLY_MOVABLE_RANGE = 2;

        private const int ROW = 0;
        private const int COLUMN = 1;

        /// <summary>
        /// Indicates whether this pawn has just moved to decide whether it is eligible for en passant or not
        /// </summary>
        public bool WasLastMove { get; set; }

        /// <summary>
        /// Overloaded constructor which initializes the Pawn piece with player id
        /// </summary>
        /// <param name="owningPlayerId">The owning player ID</param>
        public Pawn(int owningPlayerId)
        {
            OwningPlayerId = owningPlayerId;
            WasLastMove = false;
        }

        /// <summary>
        /// Finds and returns a list of coordinates which this chess piece can move vertically
        /// </summary>
        /// <returns>Coordinate of possible vertical moves</returns>
        public int[,] GetPossibleVerticalMoves()
        {
            // Multiply by -1 to show that it can also move to left
            int possibleRows = MAXIMUM_VERTICALLY_MOVABLE_RANGE * -1;
            int[,] possibleVerticalMoves = new int[MAXIMUM_VERTICALLY_MOVABLE_RANGE * 2, 2];

            for (int row = 0; row < (MAXIMUM_VERTICALLY_MOVABLE_RANGE * 2); row++)
            {
                possibleVerticalMoves[row, ROW] = possibleRows;
                possibleVerticalMoves[row, COLUMN] = 0;

                possibleRows++;
                // Do not include the current location as a possible move
                if (possibleRows == 0)
                    possibleRows++;
            }

            return possibleVerticalMoves;
        }

        /// <summary>
        /// Get all possible main diagonal moves (top left to bottom right) */
        /// </summary>
        /// <returns>Coordinates of possible main diagonal moves</returns>
        public int[,] GetPossibleMainDiagonalMoves()
        {
            int possibleRowAndColumns = MAXIMUM_DIAGONALLY_OVABLE_RANGE * -1;
            int[,] possibleMainDiagonalMoves = new int[MAXIMUM_DIAGONALLY_OVABLE_RANGE * 2, 2];

            for (int row = 0; row < (MAXIMUM_DIAGONALLY_OVABLE_RANGE * 2); row++)
            {
                possibleMainDiagonalMoves[row, ROW] = possibleRowAndColumns;
                possibleMainDiagonalMoves[row, COLUMN] = possibleRowAndColumns;

                possibleRowAndColumns++;
                // Do not include the current location
                if (possibleRowAndColumns == 0)
                    possibleRowAndColumns++;
            }

            return possibleMainDiagonalMoves;
        }

        /// <summary>
        /// Get all possible main diagonal moves (bottom left to top right
        /// </summary>
        /// <returns>Coordinates of possible minor diagonal moves</returns>
        public int[,] GetPossibleMinorDiagonalMoves()
        {
            int possibleRowAndColumns = MAXIMUM_DIAGONALLY_OVABLE_RANGE * -1;
            int[,] possibleMinorDiagonalMoves = new int[MAXIMUM_DIAGONALLY_OVABLE_RANGE * 2, 2];

            for (int row = 0; row < (MAXIMUM_DIAGONALLY_OVABLE_RANGE * 2); row++)
            {
                if (row < 8)
                {
                    possibleMinorDiagonalMoves[row, ROW] = possibleRowAndColumns;
                    possibleMinorDiagonalMoves[row, COLUMN] = possibleRowAndColumns * -1;
                }
                else
                {
                    possibleMinorDiagonalMoves[row, ROW] = possibleRowAndColumns * -1;
                    possibleMinorDiagonalMoves[row, COLUMN] = possibleRowAndColumns;
                }

                if (row < 8)
                {
                    possibleRowAndColumns++;
                    if (possibleRowAndColumns == 0)
                        possibleRowAndColumns++;
                }
                else
                {
                    possibleRowAndColumns--;
                    if (possibleRowAndColumns == 0)
                        possibleRowAndColumns--;
                }

            }
            return possibleMinorDiagonalMoves;
        }

        /// <summary>
        /// Finds and returns all the possible mvoes by this chess piece
        /// </summary>
        public override List<int[,]> AllPossibleMoves
        {
            get
            {
                List<int[,]> possibleMoves = new List<int[,]>();
                possibleMoves.Add(GetPossibleMinorDiagonalMoves());
                possibleMoves.Add(GetPossibleMainDiagonalMoves());
                possibleMoves.Add(GetPossibleVerticalMoves());
                
                return possibleMoves;
            }
        }

        /// <summary>
        /// Overriden to string method
        /// </summary>
        /// <returns>The name of the chess piece in string format</returns>
        public override string ToString()
        {
            return "Pawn";
        }
    }
}
